Title Banner

Previous Book Contents Book Index Next

Inside Macintosh: QuickDraw GX Graphics /
Chapter 5 - Bitmap Shapes / Using Bitmap Shapes


Creating Bitmaps Offscreen

The section "Converting Other Types of Shapes to Bitmaps" beginning on page 5-34 describes how you can convert a single QuickDraw GX shape to a bitmap shape. This section shows you how to draw multiple QuickDraw GX shapes to a single bitmap shape.

When you draw a shape, QuickDraw GX does the following:

Therefore, to draw shapes into an offscreen bitmap, you need to

You can find complete information about transforms, view devices, view groups, and view ports in the chapters "Transform Objects" and "View-Related Objects" in Inside Macintosh: QuickDraw GX Objects.

To create the offscreen bitmap, you must define a shape reference for the bitmap shape and create a bitmap shape of the appropriate size:

gxShape  aBitmapShape;
aBitmapShape = CreateABitmap(200, 200);
Listing 5-12 shows a possible definition for the CreateABitmap function. This function creates a black-and-white bitmap of a specified height and width.

Listing 5-12 Creating a black-and-white bitmap

static gxShape CreateABitmap(long height, long width)
{
   gxShape aBitmapShape;
   gxBitmap aBitmapGeometry;
   const gxPoint initialLocation = {ff(0), ff(0)};

   aBitmapGeometry.image = nil;

   aBitmapGeometry.width = width;
   aBitmapGeometry.height = height;
   aBitmapGeometry.rowBytes = 0;
   aBitmapGeometry.pixelSize = 1;

   aBitmapGeometry.space = gxNoSpace;
   aBitmapGeometry.set = nil;
   aBitmapGeometry.profile = nil;

   aShape = GXNewBitmap(&aBitmapGeometry, &initialLocation);

   return(aBitmapShape);
}
To create the offscreen view device, view group, and view port objects, you must declare references to them:

gxViewGroup offscreenViewGroup;
gxViewDevice offscreenViewDevice;
gxViewPort offscreenViewPort;
You create the view group object first:

offscreenViewGroup = GXNewViewGroup();
Then you can create the view device and view port objects. To create a view device, you must specify both the view group it belongs to and the bitmap it uses when rendering shapes:

offscreenViewDevice = GXNewViewDevice(offscreenViewGroup,
                                      aBitmapShape);
To create a view port, you need only specify the view group to which it belongs:

offscreenViewPort = GXNewViewPort(offscreenViewGroup);
To draw shapes to this offscreen view port, you need to create a new transform object. First, you must declare a reference to a transform object:

gxTransform offscreenTransform;
Then you can create it and set its view port list to contain the offscreen view port:

offscreenTransform = GXNewTransform();
GXSetTransformViewPorts(offscreenTransform, 1, 
                        &offscreenViewPort);
Now you're ready to draw shapes offscreen. The first shape that you draw is a simple white rectangle, and drawing it initializes the pixels in the offscreen bitmap:

gxShape aRectangleShape;
gxRectangle boundsRectangle = {ff(0), ff(0), ff(200), ff(200)};

aRectangleShape = GXNewRectangle(&boundsRectangle);

SetShapeCommonColor(aRectangleShape, gxWhite);
To draw this white rectangle to the offscreen bitmap, you must set its transform object to be the offscreen transform object:

GXSetShapeTransform(aRectangleShape, offscreenTransform);
Then you draw and dispose of the shape:

GXDrawShape(aRectangleShape);
GXDisposeShape(aRectangleShape);
Since the rectangle shape references the offscreen transform object, QuickDraw GX draws the white rectangle into the offscreen bitmap.

Because the offscreen bitmap is now initialized, you can draw other shapes to it. The following code demonstrates how to create a line shape and draw it to the offscreen bitmap:

gxShape aLineShape;
gxLine lineGeometry = {ff(40), ff(40), ff(160), ff(160)};
aLineShape = GXNewLine(&lineGeometry);
GXSetShapePen(aLineShape, ff(50));
GXSetShapeTransform(aLineShape, offscreenTransform);
GXDrawShape(aLineShape);
GXDisposeShape(aLineShape);
As another example, the following code demonstrates how to create a text shape and draw it to the offscreen bitmap:

gxShape aTextShape;
gxPoint textLocation = {ff(70), ff(100)};
gxPoint textCenter;
aTextShape = GXNewText(9, (unsigned char *) "123456789",
                       &textLocation) ;
GXGetShapeCenter(aTextShape, 0, &textCenter);
GXScaleShape(aTextShape, ff(3), ff(3), 
             textCenter.x, textCenter.y);
SetShapeCommonTransfer(aTextShape, gxXorMode);

GXSetShapeTransform(aTextShape, offscreenTransform);
GXDrawShape(aTextShape);
GXDisposeShape(aTextShape);
This code segment uses the SetShapeCommonTransfer library function, which is available in the transfer mode library.

Finally, to transfer the offscreen bitmap to the screen, you need only draw the bitmap:

GXDrawShape(aBitmapShape);
When drawing the offscreen bitmap, QuickDraw GX uses the information in the transform object of the offscreen bitmap shape. This example uses the GXNewBitmap function to create the offscreen bitmap, and so it references the same transform object as the default bitmap shape. The transform of the default bitmap references the default view port, as described in the chapter "View-Related Objects" in Inside Macintosh: QuickDraw GX Objects. Since the default view port is typically on screen, drawing the offscreen bitmap effectively transfers it to the screen.

Listing 5-13 shows the complete sample function to create an offscreen bitmap, draw shapes to it, and copy it to the screen.

Listing 5-13 Creating an offscreen bitmap

void CreateOffscreenBitmap(void)
{
   gxShape  aBitmapShape, aRectangleShape, aLineShape, aTextShape;
   
   gxRectangle boundsRectangle = {ff(0), ff(0), ff(200), ff(200)};
   gxLine lineGeometry = {ff(40), ff(40), ff(160), ff(160)};
   gxPoint textLocation = {ff(70), ff(100)};
   gxPoint textCenter;
   
   /* declare view group, and so forth. */
   aBitmapShape = CreateABitmap(200, 200);

   offscreenViewGroup = GXNewViewGroup();
   offscreenViewDevice = GXNewViewDevice(offscreenViewGroup,
                                         aBitmapShape);
   offscreenViewPort = GXNewViewPort(offscreenViewGroup);
   offscreenTransform = GXNewTransform();
   GXSetTransformViewPorts(offscreenTransform, 1, 
                           &offscreenViewPort);

   /* draw white rectangle to clear bitmap */
   aRectangleShape = GXNewRectangle(&boundsRectangle);
   GXSetShapeTransform(aRectangleShape, offscreenTransform);
   SetShapeCommonColor(aRectangleShape, gxWhite);
   GXDrawShape(aRectangleShape);
   GXDisposeShape(aRectangleShape);


   /* draw thick diagonal line offscreen */
   aLineShape = GXNewLine(&lineGeometry);
   GXSetShapePen(aLineShape, ff(50));
   GXSetShapeTransform(aLineShape, offscreenTransform);
   GXDrawShape(aLineShape);
   GXDisposeShape(aLineShape);
   
   /* draw text offscreen */
   aTextShape = GXNewText(9, (unsigned char *) "123456789",
                          &textLocation) ;
   GXGetShapeCenter(aTextShape, 0, &textCenter);
   GXScaleShape(aTextShape, ff(3), ff(3), textCenter.x, 
                textCenter.y);
   SetShapeCommonTransfer(aTextShape, gxXorMode);

   GXSetShapeTransform(aTextShape, offscreenTransform);
   GXDrawShape(aTextShape);
   GXDisposeShape(aTextShape);
   
   /* transfer bitmap to screen */
   GXDrawShape(aBitmapShape);
   GXDisposeShape(aBitmapShape);
      
   GXDisposeTransform(offscreenTransform);
   GXDisposeViewGroup(offscreenViewGroup);
}
Figure 5-29 shows the result of this function.

Figure 5-29 Multiple shapes drawn to a bitmap

The offscreen library provided with QuickDraw GX contains some utilities that simplify the creation of offscreen bitmaps. This library defines the offscreen structure, which contains a reference to a transform, view port, view device, and view group. Listing 5-14 shows how to use the offscreen library to create the bitmap shown in Figure 5-29 .

Listing 5-14 Creating an offscreen bitmap using the offscreen library

void CreateOffscreenBitmap(void)
{
   shape  aBitmapShape, aRectangleShape, aLineShape, aTextShape;
   
   offscreen anOffscreen;
   
   const gxRectangle boundsRectangle = {ff(0), ff(0), 
                                        ff(200), ff(200)};
   const gxLine lineGeometry = {ff(40), ff(40), 
                                ff(160), ff(160)};
   const gxPoint textLocation = {ff(70), ff(100)};
   gxPoint textCenter;
   
   aBitmapShape = CreateABitmap(200, 200);


   /* create all offscreen-related objects */
   CreateOffscreen(&anOffscreen, aBitmapShape);

   aRectangleShape = GXNewRectangle(&boundsRectangle);
   GXSetShapeTransform(aRectangleShape, anOffscreen.xform);
   SetShapeCommonColor(aRectangleShape, gxWhite);
   GXDrawShape(aRectangleShape);
   GXDisposeShape(aRectangleShape);

   aLineShape = GXNewLine(&lineGeometry);
   GXSetShapePen(aLineShape, ff(50));
   GXSetShapeTransform(aLineShape, anOffscreen.xform);
   GXDrawShape(aLineShape);
   GXDisposeShape(aLineShape);
   
   aTextShape = GXNewText(9, (unsigned char *) "123456789",
                          &textLocation) ;
   GXGetShapeCenter(aTextShape, 0, &textCenter);
   GXScaleShape(aTextShape, ff(3), ff(3), textCenter.x,
                textCenter.y);
   SetShapeCommonTransfer(aTextShape, gxXorMode);

   GXSetShapeTransform(aTextShape, anOffscreen.xform);
   GXDrawShape(aTextShape);
   GXDisposeShape(aTextShape);
   
   GXDrawShape(aBitmapShape);
   GXDisposeShape(aBitmapShape);

   /* dispose of all offscreen-related objects */
   DisposeOffscreen(&anOffscreen);
      
   GXDrawShape(aBitmapShape);
   GXDisposeShape(aBitmapShape);
}

Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996




Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help